Technical Q&A QA1209
Updating OpenGL Contexts


Q: OpenGL ÉRÉìÉeÉLÉXÉgÇÕǢǬÅAÇ»Ç∫çXêVÇ∑ÇÈïKóvǙdžÇÈÇÃÇ≈ǵÇÂǧǩÅH

A: OpenGL ÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅAÉhÉçÅ[ÉAÉuÉãÇÃÉWÉIÉÅÉgÉäÇ™ïœÇÌÇ¡ÇΩÇΔÇ´Ç‚ÅAÉåÉìÉ_ÉâÇ™ïœÇÌÇ¡ÇΩÇΔÇ´Ç… OpenGL ÉRÉìÉeÉLÉXÉgÇçXêVÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÉEÉCÉìÉhÉEâªÇ≥ÇÍÇΩÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃèÍçáÅAçXêVÇÕí èÌÅAíÒãüÇ≥ÇÍǃǢÇÈçXêV API Çà aglUpdateContext Ç‹ÇΩÇÕ NSOpenGLContext Çà -update ÉÅÉ\ÉbÉhÇí Ç∂ǃé¿çsÇ≥ÇÍÇ‹Ç∑ÅBÉtÉãÉXÉNÉäÅ[ÉìÉNÉâÉCÉAÉìÉgÇÃèÍçáÇÕÅAÉRÉìÉeÉLÉXÉgÇÃçXêVÇé¿çsÇ∑ÇÈÇ…ÇÕÅAçXêVä÷êîÇåƒÇ—èoÇ∑ë„ÇÌÇËÇ…ÅACGLSetFullScreen Ç‹ÇΩÇÕ aglSetFullScreen ÇÃåƒÇ—èoǵÇçƒî≠çsÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBëSëÃÇΔǵǃÅADZÇÍÇÁÇÃä÷êîÇ…ÇÊǡǃ OpenGL ÉGÉìÉWÉìÇÕÉTÅ[ÉtÉFÉCÉXÉTÉCÉYÇ™ê›íËÇ≥ÇÍÅAâºëzÉXÉNÉäÅ[ÉìÇÃïœçXÇ…çáÇÌÇπǃÉåÉìÉ_ÉâÇ™ê≥ǵÇ≠çXêVÇ≥ÇÍÇÈDZÇΔÇï€èÿÇ≈Ç´Ç‹Ç∑ÅBÉRÉìÉeÉLÉXÉgÇÃçXêVÇ…é∏îsÇ∑ÇÈÇΔÅAÉåÉìÉ_ÉäÉìÉOÇ™ïsé©ëRÇ…Ç»ÇÈÇ©ÅAOpenGL èoóÕÇ™äÆëSÇ…Ç»Ç≠Ç»ÇÈDZÇΔǙdžÇËÇ‹Ç∑ÅBç≈å„Ç…ÅAÉRÉìÉeÉLÉXÉgçXêV API ÇÃégópÇÃïâíSÇÕè¨Ç≥Ç≠ǻǢÇÃÇ≈ÅAégÇ¢âflǨǻǢÇÊǧDžǵNjÇ∑ÅBÉNÉâÉCÉAÉìÉgÇÕÅAÉtÉåÅ[ÉÄÇ≤ÇΔÇ…çXêVÇî≠çsÇ∑ÇÈÇÃÇ≈ÇÕÇ»Ç≠ÅAÉVÉXÉeÉÄÉåÉxÉãÇÃÉCÉxÉìÉgÇΔí ímÇ…âûÇ∂ǃìKêÿÇ»ÉRÉìÉeÉLÉXÉgçXêVÇÃåƒÇ—èoǵÇçsǧDZÇΔÇã≠Ç≠Ç®ä©ÇflǵNjÇ∑ÅB

Ç‹ÇΩÅAÉhÉçÅ[ÉAÉuÉãÇÃÉWÉIÉÅÉgÉäÇ‹ÇΩÇÕåªç›ÇÃÉåÉìÉ_ÉâÇ…âeãøÇó^ǶÇÈÉAÉNÉVÉáÉìÇÃdžÇΔDžLJÅAÉRÉìÉeÉLÉXÉgÇçXêVÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÉVÉXÉeÉÄÉCÉxÉìÉgÇ≈ÇÕÅAÉhÉçÅ[ÉAÉuÉãÇÃà⁄ìÆÅAÉäÉTÉCÉYÅAç¿ïWÉIÉtÉZÉbÉgÅAÇ®ÇÊÇ—ÉfÉBÉXÉvÉåÉCê›íËÇÃïœçXÅiÉfÉBÉXÉvÉåÉCÇÃê[Ç≥ÇÃïœçXÅjǙǪǧǵÇΩÉAÉNÉVÉáÉìÇ…ëäìñǵNjÇ∑ÅBDZÇÍÇÁÇÃÉCÉxÉìÉgÇÃèàóùï˚ñ@ÇÕÅAégópǵǃǢÇÈÉNÉâÉCÉAÉìÉg API Ç…ÇÊǡǃåàÇ‹ÇËÇ‹Ç∑ÅBNSOpenGLView ÇÉTÉuÉNÉâÉXâªÇµÇƒÇ¢ÇÈ Cocoa ÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅANSOpenGLView Çà -update ÉÅÉ\ÉbÉhÇé©ìÆìIÇ…åƒÇ—èoǵNjÇ∑ÅBGLUT ÉtÉåÅ[ÉÄÉèÅ[ÉNÇ≈ÇÕÉRÉìÉeÉLÉXÉgÇÃçXêVÇ™ê≥ǵÇ≠èàóùÇ≥ÇÍÇÈDZÇΔÇ™ï€èÿÇ≥ÇÍǃǢÇÈÇΩÇflÅADZÇÍÇÕ GLUT ÉAÉvÉäÉPÅ[ÉVÉáÉìDžLJìKópÇ≥ÇÍÇ‹Ç∑ÅBCocoa Ç≈èëÇ©ÇÍǃǢÇÈÇØÇÍǫLJ NSOpenGLView ÇÉTÉuÉNÉâÉXâªÇµÇƒÇ¢Ç»Ç¢ÉNÉâÉCÉAÉìÉgÇÕÅANSOpenGLContext Çà -update ÉÅÉ\ÉbÉhÇíºê⁄égópÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBAGL API ÇégÇ¡ÇΩÅAÉEÉCÉìÉhÉEâªÇ≥ÇÍǃǢÇÈ Carbon ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAaglUpdateContext ÇåƒÇ—èoÇ∑ïKóvǙdžÇËÇ‹Ç∑ÅBÉtÉãÉXÉNÉäÅ[ÉìÇà CGL Ç®ÇÊÇ— AGL ÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃèÍçáÇÕÅAÉNÉâÉCÉAÉìÉgÇÕçXêVä÷êîÇåƒÇ—èoÇ∑ÇÃÇ≈ÇÕÇ»Ç≠ÅAǪÇÍǺÇÍ CGLSetFullScreen ÇΔ aglSetFullScreen Ççƒî≠çsÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBDZÇÍÇÁÇÕÅAê[Ç≥ÅAÉTÉCÉYÅAÉfÉBÉXÉvÉåÉCê›íËÇÃïœçXÇîΩâfÇ≥ÇπÇÈÇΩÇflÇ…ïKóvÇ≈Ç∑ÅBDZÇÍÇÁÇÃçXêVåƒÇ—èoǵÇÕÅAçXêVÇïKóvÇΔÇ∑ÇÈÉVÉXÉeÉÄÉCÉxÉìÉgÇÃdžÇΔÅAÉNÉâÉCÉAÉìÉgÇ™ÉRÉìÉeÉLÉXÉgÇ÷ÇÃï`âÊÇé¿çsÇ∑ÇÈëOÇ…çsǧïKóvǙdžÇËÇ‹Ç∑ÅBç≈å„Ç…ÅAÉNÉâÉCÉAÉìÉgÇà OpenGL ÉRÉìÉeÉìÉcÇêVǵǢÉhÉçÅ[ÉAÉuÉãÇÃÉTÉCÉYÇ…çáÇÌÇπǃê≥ǵÇ≠ägëÂÅ^èkè¨Ç∑ÇÈÇΩÇflÇ…ÉhÉçÅ[ÉAÉuÉãÇ™ÉäÉTÉCÉYÇ≥ÇÍÇÈèÍçáÇÕÅAglViewport ÉRÉ}ÉìÉhÇî≠çsÇ≈Ç´Ç‹Ç∑ÅBDZDZÇ≈ÇÕÅAǪÇÍǺÇÍÇÃÉPÅ[ÉXÇ≤ÇΔÇ…ÉRÅ[Éhó·Çå©ÇƒÇ¢Ç≠ÇÃÇ™ñÇ…óßÇøÇ‹Ç∑ÅB

íçÅF
ÉRÉìÉeÉLÉXÉgÇÃçXêVÇïKóvÇΔÇ∑ÇÈDZÇÍÇÁÇÃÉVÉXÉeÉÄÉåÉxÉãÉCÉxÉìÉgÇÃíÜÇ…ÇÕÅAÉRÉìÉeÉLÉXÉgÇÃÉoÉbÉtÉ@ÇäÑÇËìñǃíºÇ∑LJÇÃǙdžÇÈÇΩÇflÅAÇ∑Ç◊ǃÇÃÉRÉìÉeÉLÉXÉgÇçXêVǵÇΩå„Ç≈ÅAÉVÅ[ÉìëSëÃÇçƒï`âÊÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅB



Cocoa ÇÃ NSOpenGLView

NSOpenGLView ÇÉTÉuÉNÉâÉXâªÇµÇƒÇ¢ÇÈ Cocoa ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAèàóùÇ∑ÇÈïKóvÇÃdžÇÈ 4 ǬÇÃÇ∑Ç◊ǃÇÃÉPÅ[ÉXDžǮǢǃÅANSOpenGLView Çà -update ÉÅÉ\ÉbÉhÇ™é©ìÆìIÇ…åƒÇ—èoÇ≥ÇÍÇ‹Ç∑ÅBÉNÉâÉCÉAÉìÉgǙDZÇÃÉÅÉ\ÉbÉhÇÉIÅ[ÉoÅ[ÉâÉCÉhǵǃÉRÉìÉeÉLÉXÉgçXêVÉCÉxÉìÉgÇéÛÇØéÊÇËÇΩÇ¢èÍçáÇÕé©óRÇ…Ç≈Ç´Ç‹Ç∑Ç™ÅAé©êgÇÃÉRÅ[ÉhÇé¿çsÇ∑ÇÈëOÇ…ïKÇ∏ [super update] ÇåƒÇ—èoǵÅAÉRÉìÉeÉLÉXÉgÇ™çXêVÇê≥ǵÇ≠èàóùǵǃǢÇÈDZÇΔÇï€èÿÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÇ‹ÇΩÅAëOèqÇÃÇÊǧDžÅAÉNÉâÉCÉAÉìÉgÇÕ -update ÉÅÉ\ÉbÉhÇêTèdÇ…égópÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÇ»Ç∫Ç»ÇÁÅADZÇÃÉÅÉ\ÉbÉhÇÕÉEÉCÉìÉhÉEÇÃÉhÉâÉbÉOéûÅAÉâÉCÉuÉäÉTÉCÉYíÜÇ…íËä˙ìIÇ…ÅAÇ®ÇÊÇ—ÉfÉBÉXÉvÉåÉCê›íËÇÃïœçXÇÃÇΩÇ—Ç…åƒÇ—èoÇ≥ÇÍÇÈÇΩÇflÅADZDZÇ≈ÇÃèàóùÇ™èdÇ≠Ç»ÇÈÇΔÅAÉEÉCÉìÉhÉEÇÃÉhÉâÉbÉOÇ‚ÉâÉCÉuÉäÉTÉCÉYÇÃÇΔÇ´Ç…ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™îΩâûǵǃǢǻǢÇÊǧDžå©Ç¶ÇƒÇµÇ‹Ç§ÇΩÇflÇ≈Ç∑ÅB


Cocoa ÇÃÉJÉXÉ^ÉÄ OpenGL ÉrÉÖÅ[

NSOpenGLView ÇÉTÉuÉNÉâÉXâªÇµÇƒÇ¢Ç»Ç¢ÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅANSOpenGLContext Çíºê⁄égópǵÅANSOpenGLContext Çà -update ÉÅÉ\ÉbÉhÇí Ç∂ǃÉAÉvÉäÉPÅ[ÉVÉáÉìÉåÉxÉãÇ≈çXêVÇèàóùÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÉäÉXÉg 1 ÇÃÉRÅ[ÉhÇÕÅAÉJÉXÉ^ÉÄ OpenGL ÉrÉÖÅ[ÉNÉâÉXÇÃàÍïîÇ≈Ç∑ÅBDZÇÃÉNÉâÉXÇÕÅAÉRÉìÉeÉLÉXÉgçXêVÇÃÉxÅ[ÉXÇΔÇ»ÇÈÉRÅ[ÉãÉoÉbÉNÇíÒãüÇ∑ÇÈ NSViewGlobalFrameDidChangeNotification Ç…ÉIÉuÉUÅ[ÉoÇí«â¡ÇµÇ‹Ç∑ÅBDZÇÃí ímÇÃåãâ ÅANSOpenGLView Ç™éÛÇØéÊÇÈÇÃÇΔìØÇ∂çXêVÅAǬNjÇËï\é¶ÇÃÉäÉTÉCÉYÅAà⁄ìÆÅAç¿ïWÉIÉtÉZÉbÉgÅAÉfÉBÉXÉvÉåÉCê›íËïœçXÇ™çsÇÌÇÍÇ‹Ç∑ÅBDZÇÃÉNÉâÉXÇΔ NSOpenGLView Ç™éÛÇØéÊÇÈÉCÉxÉìÉgÇ…ÇÕÅAé·ä±ÇÃà·Ç¢Ç™Ç†ÇËÇ‹Ç∑ÅB-update ÉÅÉ\ÉbÉhÇÕïKóvÇ»Ç∑Ç◊ǃÇÃèÍçáÅiÉäÉTÉCÉYǻǫÅjÇ…åƒÇ—èoÇ≥ÇÍÇ‹Ç∑Ç™ÅANSView ÇÕÉIÅ[ÉoÅ[ÉâÉCÉhÇ∑ÇÈì¡íËÇÃÉäÉVÉFÉCÉvÉÅÉ\ÉbÉhÇÉGÉNÉXÉ|Å[ÉgǵǻǢÇΩÇflÅA-reshape ÉÅÉ\ÉbÉhÇÕÉTÉCÉYïœçXéûÇ…ÇÕåƒÇ—èoÇ≥ÇÍÇ‹ÇπÇÒÅBÉNÉâÉCÉAÉìÉgÇÕ -drawRect ÉÅÉ\ÉbÉhÇ≈íºê⁄ÉäÉVÉFÉCÉvÇèàóùǵÅAé¿ç€Ç…ÉRÉìÉeÉìÉcÇï`âÊÇ∑ÇÈëOÇ…ÅAï\é¶îÕàÕÇ≈ïœçXÇíTÇ∑DZÇΔÇÇ®ä©ÇflǵNjÇ∑ÅBDZÇÃÉAÉvÉçÅ[É`ÇÕÅANSOpenGLView Çà -reshape ÉÅÉ\ÉbÉhÇégǧÇΔÇ´ÇΔî‰Ç◊ÅAÉpÉtÉHÅ[É}ÉìÉXÇì¡Ç…â¸ëPǵÇΩÇËí·â∫Ç≥ÇπÇΩÇËÇ∑ÇÈLJÇÃÇ≈ÇÕdžÇËÇ‹ÇπÇÒÇ™ÅAìØÇ∂åãâ Ç™ìæÇÁÇÍÇ‹Ç∑ÅBNSView ÇÃÉTÉCÉYïœçXÉçÉWÉbÉNÇ…ÉtÉbÉNÇ∑ÇÈDZÇΔÇÕÇ≈Ç´Ç‹Ç∑Ç™ÅAï°éGÇ≈džÇËÅAÉJÉXÉ^ÉÄÇà OpenGL ÉrÉÖÅ[ÉNÉâÉXÇç\ízǵǃǢÇÈ OpenGL ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕí èÌÇÕǪÇÃéËä‘ÇÇ©ÇØÇÈà”ñ°ÇÕdžÇËÇ‹ÇπÇÒÅB

#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>

// ÉRÉìÉeÉLÉXÉgçXêVÇÃèàóùï˚ñ@Çé¶Ç∑ÅA
// ÉJÉXÉ^ÉÄ OpenGL ÉrÉÖÅ[ÉNÉâÉXÇÃïîï™ìIÇ»é¿ëï

@class NSOpenGLContext, NSOpenGLPixelFormat;

@interface CustomOpenGLView : NSView
{
  @private
  NSOpenGLContext*   _openGLContext;
  NSOpenGLPixelFormat* _pixelFormat;
}

- (id)initWithFrame:(NSRect)frameRect 
        pixelFormat:(NSOpenGLPixelFormat*)format;

// ÉäÉVÉFÉCÉvÇÕÉTÉ|Å[ÉgÇ≥ÇÍǃǢǻǢÇΩÇflÅAdrawRect Ç≈îÕàÕÇçXêV
- (void)update;   // à⁄ìÆÅAÉäÉTÉCÉYÅAÉfÉBÉXÉvÉåÉCïœçX

@end

// ---------------------------------

@implementation CustomOpenGLView

- (id)initWithFrame:(NSRect)frameRect 
        pixelFormat:(NSOpenGLPixelFormat*)format
{
  self = [super initWithFrame:frameRect];
  if (self != nil) {
    _pixelFormat   = [format retain];
  }
  [[NSNotificationCenter defaultCenter] addObserver:self 
                                 selector:@selector(_surfaceNeedsUpdate:) 
                                 name:NSViewGlobalFrameDidChangeNotification
                                 object:self];
  return self;
}

// ---------------------------------

- (void)dealloc
{ // ÉRÉìÉeÉLÉXÉgÇΔÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇçÌèú
  [[NSNotificationCenter defaultCenter] removeObserver:self 
                                 name:NSViewGlobalFrameDidChangeNotification
                                 object:self];
  [self clearGLContext];
  [_pixelFormat release];
  
  [super dealloc];
}

// ---------------------------------

// NSView ÇÕì¡íËÇÃÉäÉVÉFÉCÉvÉÅÉ\ÉbÉhÇÉGÉNÉXÉ|Å[ÉgǵǻǢÇΩÇflÅAÉäÉVÉFÉCÉvÇÕǻǵ

// ---------------------------------

- (void)update
{
  if ([_openGLContext view] == self) {
    [_openGLContext update];
  }
}

// ---------------------------------

- (void) _surfaceNeedsUpdate:(NSNotification*)notification
{
  [self update];
}

@end

ÉäÉXÉg 1. NSView Ç©ÇÁîhê∂ǵÇΩÉJÉXÉ^ÉÄÇà OpenGL ÉrÉÖÅ[ÉNÉâÉX


GLUT

GLUT ÉtÉåÅ[ÉÄÉèÅ[ÉNÇégǡǃǢÇÈÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅAGLUT Ç™ÉNÉâÉCÉAÉìÉgÇΔÇÃÇ‚ÇËéÊÇËǻǵÇ≈ìKêÿÇ»ÉRÉìÉeÉLÉXÉgçXêVÇé¿çsÇ∑ÇÈÇΩÇflÅAOpenGL ÉRÉìÉeÉLÉXÉgÇ‚ÉEÉCÉìÉhÉEÇçXêVÇ∑ÇÈïKóvÇÕdžÇËÇ‹ÇπÇÒÅBDZÇÃÇÊǧǻÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAíPÇ…ÅAÉÜÅ[ÉUÇ©ÇÁÇÃê≥éÆÇ»ÉäÉTÉCÉYÇèàóùÇ∑ÇÈ GLUT ÉäÉVÉFÉCÉvÉRÅ[ÉãÉoÉbÉNÇ…âûìöÇ∑ÇÈDZÇΔÇï€èÿÇ∑ÇÈïKóvǙdžÇÈÇæÇØÇ≈Ç∑ÅB


Carbon ÇÃ AGL

Carbon API ÇégǡǃèëÇ©ÇÍÇΩ OpenGL ÉNÉâÉCÉAÉìÉgÇÃèÍçáÇÕÅAAGL ÉtÉåÅ[ÉÄÉèÅ[ÉNÇégǧDZÇΔÇ…Ç»ÇËÇ‹Ç∑ÅBÉhÉçÅ[ÉAÉuÉãÇÃÉäÉTÉCÉYÇΔà⁄ìÆÇÃÉCÉxÉìÉgÇèàóùÇ∑ÇÈç≈LJíPèÉÇ»ï˚ñ@ÇÕÅACarbon ÉCÉxÉìÉgÇóòópÇ∑ÇÈDZÇΔÇ≈Ç∑ÅBÉhÉçÅ[ÉAÉuÉãÇÃÉäÉTÉCÉYÇΔà⁄ìÆÇëŒè€ÇΔÇ∑ÇÈÇÃÇ≈džÇÍÇŒÅAÉEÉCÉìÉhÉEÉCÉxÉìÉgÇà kEventWindowBoundsChanged ÇΔ kEventWindowZoomed ÇèàóùÇ∑ÇÈÇæÇØÇ≈è\ï™Ç≈Ç∑ÅBkEventWindowBoundsChanged ÉCÉxÉìÉgÇÕÅAÅuÉâÉCÉuÅvÇà ÉEÉCÉìÉhÉEÉäÉTÉCÉYÇΔÉEÉCÉìÉhÉEÉhÉâÉbÉOÇÃç€Ç…î≠ê∂Ç∑ÇÈÇΩÇflÅAïKóvÇ»ÉPÅ[ÉXÇÃëÂïîï™Ç™èàóùÇ≥ÇÍÇ‹Ç∑ÅBkEventWindowZoomed ÉEÉCÉìÉhÉEÉCÉxÉìÉgÇÕÅAïtâ¡ìIÇ»ÉEÉCÉìÉhÉEÉYÅ[ÉÄÇÃÉPÅ[ÉXÇèàóùǵNjÇ∑ÅBDZÇÍÇÁÇà Carbon ÉCÉxÉìÉgÇÃè⁄ç◊DžǬǢǃÇÕÅACarbon ÉCÉxÉìÉgÇÃÉhÉLÉÖÉÅÉìÉg ÇΔÅAÅuCarbonEvents.hÅvÉtÉåÅ[ÉÄÉèÅ[ÉNÉwÉbÉ_ÇéQèΔǵǃÇ≠ÇæÇ≥Ç¢ÅBÉäÉXÉg 2 ÇÃÉRÅ[ÉhÇÕÅADZÇÍÇÁÇÃÉCÉxÉìÉgÅiÇΔǪÇÃëºÅjÇèàóùÇ∑ÇÈíPèÉÇ»ÉEÉCÉìÉhÉEÉCÉxÉìÉgÉnÉìÉhÉâÇé¶ÇµÇƒÇ¢Ç‹Ç∑ÅBDZÇÃÉTÉìÉvÉãÇ≈ÇÕÅAÉEÉCÉìÉhÉEÉCÉxÉìÉgÉnÉìÉhÉâÇÕÅAÉäÉXÉg 3 Ç…é¶Ç∑ resizeGL ÉãÅ[É`ÉìÇåƒÇ—èoǵNjÇ∑ÅB

#include <Carbon/Carbon.h>
// íçÅFÉTÉ|Å[ÉgÉãÅ[É`ÉìÇà handleWindowUpdate()ÅAdisposeGL()ÅA
//       buildGL() ÇÕì«é“ÇÃï˚Ç÷ÇÃâ€ëËÇΔǵǃécǵǃǮÇ≠
//       resizeGL() ÇÕÉäÉXÉg 3 Ç…é¶Ç∑

static pascal OSStatus windowEvtHndlr (EventHandlerCallRef myHandler, 
                                       EventRef event, 
                                       void* userData)
{
  WindowRef     window;
  AGLContext    aglContext = (AGLContext) userData; // ÉRÉìÉeÉLÉXÉgÇÃÉXÉgÉåÅ[ÉW
  Rect          rectPort = {0,0,0,0};
  OSStatus      result = eventNotHandledErr;
  UInt32        class = GetEventClass (event);
  UInt32        kind = GetEventKind (event);

  GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 
                    NULL, sizeof(WindowRef), NULL, &window);
  if (window) {
    GetWindowPortBounds (window, &rectPort);
  }
  switch (class) {
    // ëºÇÃéÌófiÇÃÉCÉxÉìÉgÇDZDZÇ≈èàóù
    case kEventClassWindow:
      switch (kind) {
        case kEventWindowActivated: // ÉNÉäÉbÉNãNìÆÅAç≈èâÇÃÉtÉâÉbÉVÉÖÇ
          // ñhÇÆÇΩÇflÇ…ÅAç≈èâÇÕà”ê}ìIÇ…í âfl
        case kEventWindowDrawContent:
          // ÉEÉCÉìÉhÉEçXêVä÷êîÇåƒÇ—èoÇ∑ÅAÇΩÇΔǶnj...
          handleWindowUpdate(window);
          break;
        case kEventWindowClose: // ÉEÉCÉìÉhÉEÇ™ï¬Ç∂ÇÁÇÍǃǢÇÈÅiÉNÉçÅ[ÉYÉ{ÉbÉNÉXÅj
          HideWindow (window);
          // OpenGL ÇÃîjä¸ä÷êîÇåƒÇ—èoÇ∑ÅAÇΩÇΔǶnj...
          disposeGL (window);
          break;
        case kEventWindowShown: // ç≈èâÇÃï\é¶Åiç≈è¨âªÇÃâèúà»äOÅj
          // OpenGL ÇÃÉZÉbÉgÉAÉbÉvä÷êîÇåƒÇ—èoÇ∑ÅAÇΩÇΔǶnj...
          buildGL (window);
          if (window == FrontWindow ())
            SetUserFocusWindow (window);
          InvalWindowRect (window, &rectPort);
          break;
        case kEventWindowBoundsChanged: // ÉäÉTÉCÉYÇΔà⁄ìÆÅiÉhÉâÉbÉOÅj
          resizeGL (window, aglContext);
          // ÉEÉCÉìÉhÉEçXêVä÷êîÇåƒÇ—èoÇ∑ÅAÇΩÇΔǶnj...
          handleWindowUpdate(window); // ÉâÉCÉuÉäÉTÉCÉYÇÃÇΩÇflÇ…ã≠êßìIÇ…çXêV
          // íçà”ÅFÉEÉCÉìÉhÉEÇÃçƒï`âÊÇ™íxÇ¢ÇΔÉhÉâÉbÉOÇÃÉpÉtÉHÅ[É}ÉìÉXÇ…âeãøÇ∑ÇÈ
          break;
        case kEventWindowZoomed: // ÉÜÅ[ÉUÇ™ÉYÅ[ÉÄÉ{É^ÉìÇÉNÉäÉbÉN
          resizeGL (window, aglContext);
          break;
      }
      break;
  }
  return result;
}

ÉäÉXÉg 2. Carbon ÉEÉCÉìÉhÉEÉCÉxÉìÉgÉnÉìÉhÉâ

ÉRÉìÉeÉLÉXÉgçXêVÇèàóùÇ∑ÇÈé¿ç€ÇÃÉRÅ[ÉhÇÉäÉXÉg 3 Ç…é¶ÇµÇ‹Ç∑ÅBǪÇÃç≈LJíPèÉÇ»å`éÆÇ≈ÅADZÇÃÉRÅ[ÉhÇÕÅAëŒè€ÇÃÉRÉìÉeÉLÉXÉgÇ™ aglSetCurrentContext Ç≈åªç›ÇÃÉRÉìÉeÉLÉXÉgÇ…Ç»ÇÈDZÇΔÇï€èÿǵÅAǪÇÃÉRÉìÉeÉLÉXÉgÇ…ëŒÇµÇƒ aglUpdateContext ÇåƒÇ—èoǵNjÇ∑ÅBëOèqÇÃÇÊǧDžÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕ glViewport ÇÕåƒÇ—èoǵÅAÉhÉçÅ[ÉAÉuÉãÇÃÉTÉCÉYÇÉRÅ[ÉhÉäÉXÉgÇ…é¶Ç∑ÇÊǧDžåªç›ÇÃÉEÉCÉìÉhÉEÉTÉCÉYÅAÇ‹ÇΩÇÕà”ñ°ÇÃdžÇÈëºÇÃílÇ…çXêVÇ∑ÇÈDZÇΔLJÇ≈Ç´Ç‹Ç∑ÅBÇ≥ÇÁÇ…ÅAÉNÉâÉCÉAÉìÉgÇÕÅAÉEÉCÉìÉhÉEÇÃÉTÉCÉYÇΔǪÇÃëäëŒìIÇ»ÉWÉIÉÅÉgÉäÇ™ïœçXÇ≥ÇÍǃǩÇÁï`âÊÉãÅ[É`ÉìÇégÇ¡ÇƒÇ‹ÇæçXêVǵǃǢǻǢèÍçáÇ…ÅADZÇÃã@âÔÇóòópǵǃǪÇÃìäâeçsóÒÇçXêVÇ≈Ç´Ç‹Ç∑ÅB

#include <Carbon/Carbon.h>
#include <AGL/agl.h>
#include <OpenGL/OpenGL.h>

// GL ÇÃÉäÉTÉCÉYÇèàóù
// - ÉRÉìÉeÉLÉXÉgÇÃçXêVÇ™ïKóvÇ≈džÇËÅAÉEÉCÉìÉhÉEÉTÉCÉYÇ™ïœçXÇ≥ÇÍÇΩèÍçáÅA
//   ÉEÉCÉìÉhÉEÉTÉCÉYÇçXêVǵǃÅAÉrÉÖÅ[É|Å[ÉgÇÉäÉZÉbÉg

void resizeGL (WindowRef window, AGLContext aglContext)
{
  Rect rectPort;

  aglSetCurrentContext (aglContext);
  aglUpdateContext (aglContext);

  GetWindowPortBounds (window, &rectPort);
  glViewport (0, 0, rectPort.right - rectPort.left, 
                    rectPort.bottom - rectPort.top);
  // ïKóvÇ…âûÇ∂ǃÅADZDZÇ≈ìäâeçsóÒÇçXêV
}

ÉäÉXÉg 3. Carbon ÉRÉìÉeÉLÉXÉgçXêVÉnÉìÉhÉâ

Carbon ÉfÉBÉXÉvÉåÉCê›íËïœçXÇÃèàóùÇÕé·ä±ï°éGÇ≈Ç∑Ç™ÅAîÒèÌÇ…çáóùìIÇ≈Ç∑ÅBÉfÉBÉXÉvÉåÉCê›íËÇÃïœçXÇÕÅADisplay Manager ÉRÅ[ÉãÉoÉbÉNä÷êîÇégǡǃåüèoÇ≈Ç´Ç‹Ç∑ÅBDZÇà API ÇÕ Carbon ÉtÉåÅ[ÉÄÉèÅ[ÉNÇ≈LJóòópâ¬î\Ç≈ÅAǪÇÃÉvÉçÉgÉ^ÉCÉvÇ™ Displays.h ÉwÉbÉ_ÉtÉ@ÉCÉãÇÃíÜDždžÇËÇ‹Ç∑ÅBÉfÉxÉçÉbÉpÇÕÅADMExtendedNotificationProcPtr ÉRÅ[ÉãÉoÉbÉN API Ç…èÄãíǵÇΩÉRÅ[ÉãÉoÉbÉNä÷êîÇópà”Ç∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBéüÇ…ÅANewDMExtendedNotificationUPP Çí Ç∂ǃDZÇÃä÷êîÇ÷Çà UPP (Universal Procedure Pointer) ÇçÏê¨ÇµÅADZÇà UPP Ç Display Manager Çà DMRegisterExtendedNotifyProc Ç…ìoò^ǵNjÇ∑ÅBÉNÉâÉCÉAÉìÉgÇ™ï°êîÇÃÉRÉìÉeÉLÉXÉgÇ‹ÇΩÇÕÉEÉCÉìÉhÉEÇégǡǃǢÇÈèÍçáÇÕÅAÉäÉXÉg 4 Ç…é¶Ç∑ÇÊǧDžÅAÉEÉCÉìÉhÉEÅAÇ‹ÇΩÇÕÉRÉìÉeÉLÉXÉgÇÉÜÅ[ÉUÉfÅ[É^Ç…í«â¡Ç∑ÇÈÇÃÇ™ñÇ…óßǬDZÇΔǙdžÇËÇ‹Ç∑ÅBÉRÅ[ÉãÉoÉbÉNä÷êîé©ëÃÇÕíPèÉǻLJÇÃÇ≈ÅAè„ãLÇÃÉäÉXÉg 3 Ç…é¶Ç∑ÇÊǧDžÉRÉìÉeÉLÉXÉgçXêVÉãÅ[É`ÉìÇÃåƒÇ—èoǵǩÇÁÇ»ÇËÅAÉtÉãÉEÉCÉìÉhÉEÇÃÉOÉâÉtÉBÉbÉNÉXÉ|Å[ÉgãÈå`Çñ≥å¯Ç…ǵǃçXêVÉCÉxÉìÉgÇã≠êßǵNjÇ∑ÅBÉRÅ[ÉãÉoÉbÉNÇ…ëóÇÁÇÍÇÈÉÅÉbÉZÅ[ÉWÉ^ÉCÉvÇΔǵǃ kDMNotifyEvent ÇíTÇ∑DZÇΔÇ…ÇÊǡǃÅAÉCÉxÉìÉgÇ™é¿ç€Ç…Åuí ímÅvÉCÉxÉìÉgÇ≈džÇÈDZÇΔÇïKÇ∏ämîFÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBí ímÉCÉxÉìÉgà»äODžLJÅAÉRÉìÉeÉLÉXÉgçXêVÇÃèàóùÇ≈ÉNÉâÉCÉAÉìÉgÇ™ëŒèàÇ∑ÇÈïKóvÇÃǻǢ Display Manager ÉCÉxÉìÉgǙdžÇËÇ‹Ç∑ÅBÉäÉXÉg 4 Ç…ÇÕÅAÉRÅ[ÉãÉoÉbÉNÅAUPP ÇÃçÏê¨ÇΔìoò^ÅAǪǵǃç≈å„Ç…ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™ Display Manager ÇÃí ímÇïKóvÇΔǵǻÇ≠ǻǡÇΩèÍçáÇÃÅADisposeDMExtendedNotificationUPP Ç…ÇÊÇÈ UPP ÇÃîjä¸Çé¶ÇµÇ‹Ç∑ÅB

#include <Carbon/Carbon.h>
#include <AGL/agl.h>

// ÉRÉìÉeÉLÉXÉgÇÕ userData Çí Ç∂ǃìnÇ≥ÇÍÇÈ
void handleWindowDMEvent (void *userData, short msg, void *notifyData)
{
  AGLContext aglContext = (AGLContext) userData; // ÉRÉìÉeÉLÉXÉgÇÃÉXÉgÉåÅ[ÉW
  if (kDMNotifyEvent == msg) { // ïœçXí ímÇÃÇ›ÇëóÇÈ
    resizeGL (window, agContext); // ÉRÉìÉeÉLÉXÉgÇÃçXêVÇΔÉäÉTÉCÉYÇÃèàóù
    GetWindowPortBounds (window, &rectPort);
    InvalWindowRect (window, &rectPort); // ã≠êßìIÇ…çƒï`âÊ
  }
}

// ---------------------------------

void setupDMNotify (WindowRef window)
{
  // ÉfÉBÉXÉvÉåÉCê›íËÇ™ïœçXÇ≥ÇÍÇΩÇΔÇ´Ç…ïKÇ∏í ímÇ≥ÇÍÇÈÇÊǧDžÇ∑ÇÈ
  gWindowEDMUPP = NewDMExtendedNotificationUPP (handleWindowDMEvent);
  DMRegisterExtendedNotifyProc (gWindowEDMUPP, (void *)window, NULL, &psn);
}

// ---------------------------------

OSStatus disposeDM Notify (WindowRef window)
{
  if (gWindowEDMUPP) { // DM í ímÇà UPP Çîjä¸
    DisposeDMExtendedNotificationUPP (gWindowEDMUPP);
    gWindowEDMUPP = NULL;
  }
}

ÉäÉXÉg 4. Display Manager í ímÉnÉìÉhÉâ


ÉtÉãÉXÉNÉäÅ[ÉìÇà AGL ÇΔ CGL

ÉtÉãÉXÉNÉäÅ[ÉìÇà AGL ÇΔ CGL ÇégópÇ∑ÇÈÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃèÍçáÇÕÅAçÏãΔÇÕLJǧè≠ǵíPèÉÇ…Ç»ÇËÇ‹Ç∑ÅBÉhÉçÅ[ÉAÉuÉãÇÃà íuÇ™å≈íËÇ≥ÇÍÅAÉTÉCÉYÇÕÉfÉBÉXÉvÉåÉCê›íËÇ…íºê⁄åãÇ—ïtǢǃǮÇËÅADZÇÃê›íËÇ™ÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃêßå‰â∫DždžÇÈÇΩÇflÅAÉtÉãÉXÉNÉäÅ[ÉìÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕé¿ç€Ç…ê›íËÇïœçXǵÇΩèÍçáÇ…ÅAíPÇ…çXêVÇé¿çsÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÉtÉãÉXÉNÉäÅ[ÉìÉNÉâÉCÉAÉìÉgÇ≈ÇÕÅAÉRÉìÉeÉLÉXÉgçXêVÉãÅ[É`ÉìÇåƒÇ—èoÇ∑ë„ÇÌÇËÇ…ÅAÉtÉãÉXÉNÉäÅ[ÉìÇÉZÉbÉgÇ∑ÇÈåƒÇ—èoǵÇçƒî≠çsÇ∑ÇÈÇæÇØÇ≈Ç∑ÅBÉäÉXÉg 5 ÇΔ 6 ÇÕÅAǪÇÍǺÇÍÉtÉãÉXÉNÉäÅ[ÉìÉRÉìÉeÉLÉXÉgÇÉäÉZÉbÉgÇ∑ÇÈ AGL ÉãÅ[É`ÉìÇΔ CGL ÉãÅ[É`ÉìÇÃó·Ç≈Ç∑ÅBAGL ÇÃèÍçáÇÕÅAaglSetFullScreen ä÷êîÇ™ÉXÉNÉäÅ[ÉìÉLÉÉÉvÉ`ÉÉÇΔÉfÉBÉXÉvÉåÉCÉäÉTÉCÉYÇèàóùÇ∑ÇÈÇΩÇflÅAresizeGL ÇåƒÇ—èoÇ∑ëOÇ…ÅAóLå¯Ç»ÉtÉãÉXÉNÉäÅ[ÉìÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇΔÉRÉìÉeÉLÉXÉgÇ™çÏê¨Ç≥ÇÍǃǢÇÈDZÇΔÇï€èÿÇ∑ÇÈïKóvǙdžÇÈÇæÇØÇ≈Ç∑ÅBCGL ÇÃèÍçáÇÕÅACGCaptureAllDisplaysÅACGDisplayBestModeForParametersAndRefreshRateÅiÇ‹ÇΩÇÕÅAä÷òAÇ∑ÇÈ CGDirectDisplay ä÷êîÅjÅAÇ®ÇÊÇ— CGDisplaySwitchToMode ÇégǡǃÅAóvãÅÇ≥ÇÍÇΩÉfÉBÉXÉvÉåÉCê›íËÇÉZÉbÉgǵÅAéüÇ…ÉfÉBÉXÉvÉåÉCÇÃÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇê›íËǵÅAresizeGL ÇåƒÇ—èoǵNjÇ∑ÅBÉäÉXÉg 7 Ç…ÅACGL Ç≈égópÇ≈Ç´ÇÈÇÊǧDž OpenGL Çê›íËÇ∑ÇÈó·Çé¶ÇµÇ‹Ç∑ÅB

íçÅF
AGL_FS_CAPTURE_SINGLE Çê›íËÇπÇ∏Ç… aglSetFullScreen ÇégǧǩÅAÇ‹ÇΩÇÕ CGCaptureAllDisplays ÇégǡǃÇ∑Ç◊ǃÇÃÉfÉBÉXÉvÉåÉCÇÉLÉÉÉvÉ`ÉÉÇ∑ÇÈÇΔÅAÉfÉBÉXÉvÉåÉCê›íËÇ™å≈íËÇ≥ÇÍǃǮÇËÅAâï˙Ç∑ÇÈÇ‹Ç≈ïœÇÌÇÁǻǢÇΩÇflÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕ Display Manager ÇÃí ímÇéÛÇØéÊÇËÇ‹ÇπÇÒÅBÉNÉâÉCÉAÉìÉgÇ™ÅAÇ∑Ç◊ǃÇÃÉfÉBÉXÉvÉåÉCÇÉLÉÉÉvÉ`ÉÉǵǃǢǻǢèÍçáÅAÉLÉÉÉvÉ`ÉÉÇ≥ÇÍǃǢǻǢÉfÉBÉXÉvÉåÉCÇÃÉfÉBÉXÉvÉåÉCê›íËÇÃïœçXÇÕàÀëRÇΔǵǃéÛÇØéÊÇËÇ‹Ç∑ÅBDZÇÃÇÊǧǻí ímÇÕÅAåªç›ÇÕÉfÉBÉXÉvÉåÉCÇ…ÇÕégópÇ≥ÇÍǃǮÇÁÇ∏ÅAÉtÉãÉXÉNÉäÅ[ÉìÇà OpenGL ÇÃèàóùÇÃëŒè€Ç≈ÇÕǻǢÇΩÇflÅAí èÌÅAÉtÉãÉXÉNÉäÅ[ÉìÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅADZÇÃÇÊǧǻÉfÉBÉXÉvÉåÉCí ímÇèàóùÇ∑ÇÈïKóvǙdžÇËÇ‹ÇπÇÒÅB


#include <Carbon/Carbon.h>
#include <AGL/agl.h>
#include <OpenGL/gl.h>

// ÉXÉNÉäÅ[ÉìÇÃÉäÉTÉCÉYÇΔçXêVÇ…ïKóvÇ»ÉRÉìÉeÉLÉXÉgÇèàóùÅB
// ÉtÉãÉXÉNÉäÅ[ÉìÅAégópÇ∑ÇÈíPàÍÇà GDeviceÅAê›íËÇ∑ÇÈÉsÉNÉZÉãê[Ç≥
// ÇéwíËÇ∑ÇÈÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇ≈ÉRÉìÉeÉLÉXÉgÇ™çÏê¨Ç≥ÇÍǃ
// Ç¢ÇÈDZÇΔÇëOíÒÇΔÇ∑ÇÈÅB

void resizeGL (AGLContext aglContext, GLSizei height, GLSizei width)
{
  GLint displayCaps [3];

  if (!aglContext) // óLå¯Ç»ÉRÉìÉeÉLÉXÉgǩǫǧǩÇÉ`ÉFÉbÉN
    return;

  // ÉRÉìÉeÉLÉXÉgÇ™ämé¿Ç…çXêVÇ≥ÇÍÇÈÇÊǧDžÅAÉhÉçÅ[ÉAÉuÉãÇçƒìxÉAÉ^ÉbÉ`
  aglSetCurrentContext (aglContext);
  aglSetFullScreen (aglContext, width, height, 0, 0);
  // íçà”ÅFê[Ç≥ÇÕÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇ≈ê›íËÅAé¸îgêî 0 ÇÕÇ∑Ç◊ǃDžÉ}ÉbÉ`
  // 0 ÉfÉBÉXÉvÉåÉCÇÕÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇ≈ëIëÇ≥ÇÍÇΩíPàÍÇÃÉfÉBÉXÉvÉåÉCÇëIë
  
  aglGetInteger (aglContext, AGL_FULLSCREEN, displayCaps); // ÉTÉCÉYÇéÊìæ
  glViewport (0, 0, displayCaps[0], displayCaps[1]);
  // ïKóvÇ…âûÇ∂ǃÅADZDZÇ≈ìäâeçsóÒÇçXêV
}

ÉäÉXÉg 5. ÉtÉãÉXÉNÉäÅ[Éì AGL çXêVÇÃèàóù


#include <Carbon/Carbon.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>

// ÉRÉìÉeÉLÉXÉgÇÃçXêVÇ…ïKóvÇ»çƒÉAÉ^ÉbÉ`ÇèàóùÅB
// ÉtÉãÉXÉNÉäÅ[ÉìÅAégópÇ∑ÇÈíPàÍÇÃÉfÉBÉXÉvÉåÉCÅAê›íËÇ∑ÇÈÉsÉNÉZÉãê[Ç≥
// ÇéwíËÇ∑ÇÈÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇ≈ÉRÉìÉeÉLÉXÉgÇ™çÏê¨Ç≥ÇÍǃ
// Ç¢ÇÈDZÇΔÇëOíÒÇΔÇ∑ÇÈÅB
// Ç≥ÇÁÇ…ÅAÉXÉNÉäÅ[ÉìÇ™ÉLÉÉÉvÉ`ÉÉÇ≥ÇÍÅAóvãÅÇ≥ÇÍÇΩÉTÉCÉYÇ…ê›íËÇ≥ÇÍǃ
// Ç¢ÇÈDZÇΔÇëOíÒÇΔÇ∑ÇÈÅBåƒÇ—èoǵÉãÅ[É`ÉìÇÕé¿ç€ÇÃÉfÉBÉXÉvÉåÉCÉTÉCÉY
// ÇÃê›íËÇé¿ç€Ç…èàóùÇ∑ÇÈÇΩÇflÅADZDZÇ≈ÇÕÉrÉÖÅ[É|Å[ÉgÇÕê›íËÇ≥ÇÍǻǢÅB


void resizeGL (CGLContextObj cglContext)
{
  if (!cglContext) // óLå¯Ç»ÉRÉìÉeÉLÉXÉgǩǫǧǩÉ`ÉFÉbÉN
    return;

  // ÉRÉìÉeÉLÉXÉgÇ™ämé¿Ç…çXêVÇ≥ÇÍÇÈÇÊǧDžÅAÉhÉçÅ[ÉAÉuÉãÇçƒìxÉAÉ^ÉbÉ`
  CGLSetCurrentContext (cglContext);
  CGLSetFullScreen (cglContext);
}

ÉäÉXÉg 6. ÉtÉãÉXÉNÉäÅ[Éì CGL çXêVÇÃèàóù


#include <Carbon/Carbon.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>

// ÉtÉãÉXÉNÉäÅ[ÉìÇÃÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgÇÃçÏê¨ÅAÉfÉBÉXÉvÉåÉCÉLÉÉÉvÉ`ÉÉÅA
// Ç®ÇÊÇ—ÉäÉTÉCÉYÇÃó·Çé¶Ç∑ÉRÅ[ÉhÅBÇ≥ÇÁÇ…ä÷òAÇ∑ÇÈ
// âèúÉRÅ[ÉhLJé¶Ç∑ÅB

// âèúÇ…égópÇ∑ÇÈÉOÉçÅ[ÉoÉãïœêî
CGDirectDisplayID gDisplay = 0;
CFDictionaryRef gOldDisplayMode = NULL;
GLboolean gOldDisplayModeValid = GL_FALSE;

CGLContextObj buildFullScreenGL (size_t width, size_t height, 
                                 size_t depth, CGRefreshRate refresh)
{
  CGLContextObj cglContext = 0;
  CGLPixelFormatAttribute attribs[] = {kCGLPFADisplayMask, 0, 
                                       kCGLPFAFullScreen, 
                                       kCGLPFADoubleBuffer, 
                                       kCGLPFADepthSize, 16, NULL};
  CGLPixelFormatObj pixelFormat = NULL;
  long numPixelFormats = 0;
  CFDictionaryRef refDisplayMode = 0;
  CGRect displayRect;

  // ÉfÉBÉXÉvÉåÉCÉÇÅ[ÉhÇê›íË
  gDisplay = CGMainDisplayID (); // ÉÅÉCÉìÇÃÉfÉBÉXÉvÉåÉCÇégóp
  refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate 
                        (gDisplay, depth, width, height, refresh, NULL);
  if (refDisplayMode) {
    gOldDisplayMode = CGDisplayCurrentMode (gDisplay);
    gOldDisplayModeValid = GL_TRUE;
    CGCaptureAllDisplays ();
    CGDisplaySwitchToMode (gDisplay, refDisplayMode);
  } // ǪÇÍà»äOÇÃåªç›ÇÃÉÇÅ[ÉhÇégóp
  
  // ÉRÉìÉeÉLÉXÉgÇç\íz
  attribs[1] = CGDisplayIDToOpenGLDisplayMask (gDisplay); // PF ÉfÉBÉXÉvÉåÉCÇê›íË
  CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats);
  if (pixelFormat) {
    CGLCreateContext (pixelFormat, NULL, &cglContext);
    CGLDestroyPixelFormat (pixelFormat);
  }
  if (cglContext) {
    resizeGL (cglContext);
    displayRect = CGDisplayBounds (gDisplay);
    glViewport (0, 0, displayRect.size.width, displayRect.size.height);
    // ïKóvÇ…âûÇ∂ǃÅAìäâeçsóÒÇçXêVÇ≈Ç´ÇÈ

    // DZDZÇ≈ OpenGL ÇÃèÛë‘ÇÉZÉbÉgÉAÉbÉv
  }
  return cglContext;
}

// ---------------------------------

void disposeGL (CGLContextObj cglContext)
{
  // ÉRÉìÉeÉLÉXÉgÇÉ_ÉìÉv
  CGLSetCurrentContext (NULL);
  CGLClearDrawable (cglContext);
  if (cglContext)
    CGLDestroyContext (cglContext);   

  // ìKêÿÇ»âëúìxÇ…êÿÇËë÷Ƕ
  if (gOldDisplayModeValid)
    CGDisplaySwitchToMode(gDisplay, gOldDisplayMode);
  gOldDisplayModeValid = GL_FALSE;
  CGReleaseAllDisplays ();
}

ÉäÉXÉg 7. ÉtÉãÉXÉNÉäÅ[Éì CGL ÉfÉBÉXÉvÉåÉCÇÃê›íËÇΔâèúÇÃó·


íçÅF
CGL ÇÕ CGDirectDisplayID ÇÃë„ÇÌÇËÇ…ÅAÉsÉNÉZÉãÉtÉHÅ[É}ÉbÉgëÆê´ÇÃíÜÇ≈ CGOpenGLDisplayMask ÇégǡǃÅAÉtÉãÉXÉNÉäÅ[ÉìÉRÉìÉeÉLÉXÉgÇ…égǧÉfÉBÉXÉvÉåÉCÇéwíËǵNjÇ∑ÅBDZÇÃëÆê´ÇÕ kCGLPFADisplayMask éwíËéqÇΔÅAǪÇÃdžÇΔÇ…é¿ç€ÇÃÉfÉBÉXÉvÉåÉCÉ}ÉXÉNÇë±ÇØÇÈDZÇΔÇ…ÇÊǡǃê›íËǵNjÇ∑ÅBDZÇÃÉ}ÉXÉNÇÕ CGDisplayIDToOpenGLDisplayMask ä÷êîÇégǡǃÅAóvãÅÇ≥ÇÍÇΩÉfÉBÉXÉvÉåÉCÇà CGDirectDisplayID ÇìnÇ∑DZÇΔÇ…ÇÊǡǃå©Ç¬ÇØÇÁÇÍÇ‹Ç∑ÅB


óvñÒÇ∑ÇÈÇΔÅAOpenGL API ÇÃÉNÉâÉCÉAÉìÉgÇÕÅAÉåÉìÉ_ÉâÇΔÉWÉIÉÅÉgÉäÇÃïœçXÇ…çáÇÌÇπǃ OpenGL ÉRÉìÉeÉLÉXÉgÇ™çXêVÇ≥ÇÍÇÈDZÇΔÇï€èÿÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBDZÇÍÇÕÉhÉçÅ[ÉAÉuÉãÇÃÉWÉIÉÅÉgÉäÇïœçXÇ∑ÇÈÉCÉxÉìÉgÅiÉTÅ[ÉtÉFÉXÇÃå¥ì_ÅAïùÅAçÇÇ≥ÅAÉsÉNÉZÉãÇÃê[Ç≥ÅAÉhÉçÅ[ÉAÉuÉãÇÃà íuÅAÉfÉBÉXÉvÉåÉCê›íËǻǫÅjÇ…âûìöǵǃÅAÉVÉXÉeÉÄ API Ç‹ÇΩÇÕ ÉNÉâÉCÉAÉìÉgé©êgÇ…ÇÊǡǃèàóùÇ≥ÇÍÇ‹Ç∑ÅBCarbon API ÇÃèÍçáÇÕÅAÉEÉCÉìÉhÉEâªÇ≥ÇÍÇΩÉNÉâÉCÉAÉìÉgÇ≈ÇÕ aglUpdateContext ÇåƒÇ—èoÇ∑ïKóvǙdžÇËÇ‹Ç∑ÅBÉtÉãÉXÉNÉäÅ[ÉìÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAaglSetFullScreen Ç‹ÇΩÇÕ CGLSetFullScreen ÇégópǵǃÅAÉtÉãÉXÉNÉäÅ[ÉìÇÃÉhÉçÅ[ÉAÉuÉãÇçƒç\ízÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBNSOpenGLView ÉTÉuÉNÉâÉXÇégópǵǃǢÇÈ Cocoa ÉNÉâÉCÉAÉìÉgÇΔ GLUT ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAçXêVÇÕÉVÉXÉeÉÄ API Ç…ÇÊǡǃèàóùǵNjÇ∑ÅBç≈å„Ç…ÅAÉJÉXÉ^ÉÄÇà OpenGL ÉrÉÖÅ[ÉNÉâÉXÇégópǵǃǢÇÈ Cocoa ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAÉWÉIÉÅÉgÉäÇÃïœçXÇ™í ímÇ≥ÇÍÇΩÇΔÇ´Ç…ÅANSOpenGLContext Çà -update ÉÅÉ\ÉbÉhÇåƒÇ—èoÇ∑ïKóvǙdžÇËÇ‹Ç∑ÅBè„ãLÇÃÉÅÉ\ÉbÉhÇégópÇ∑ÇÈÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅAÉåÉìÉ_ÉâÇ™ïœçXÇ≥ÇÍÇΩÇËÅAÉÜÅ[ÉUÇ™ÉhÉçÅ[ÉAÉuÉãÇïœçXǵÇΩÇËǵÇΩÇΔÇ´Ç…ñ‚ëËÇ»Ç≠ìÆçÏǵǃÅAó«çDÇ»ÉÜÅ[ÉUëÃå±Çé¿åªÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅB


[2003 îN 6 åé 19 ì˙]